home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus Leser 15 / Amiga Plus Leser CD 15.iso / Tools / Hardware / BlizKick / applypatch.e next >
Encoding:
Text File  |  2002-03-13  |  12.5 KB  |  535 lines

  1. -> FILE: ESrc:Own/applypatch.e          REV: 8 --- apply BlizKick patch module to rom
  2. /* History
  3.    0      started 11th Dec 1999.
  4.    1      works.
  5.    2      12th Dec: added SPEEDROM
  6.    3      added HOGWAITBLIT
  7.    4      added test for <>$f80000 rom
  8.    5      no longer requires MODULES arg, now tests if any patches
  9.           was applied.
  10.    6      27th Mar 2000: added elfloadseg-patch ioerr bug workaround.
  11.    7      12th Oct 2000: fixed small bug in SPEEDROM: the RT_END of the last
  12.           ROMTag was made to point to $fffffe. Due some funny side effect
  13.           ($1000000 - $fffffe) / 2 - 1 = 0) it caused the ROM's ROMTag scanner
  14.           access longword at $fffffe, thus accessing non-existent memory.
  15.           (maybe this was it Gunther... :-)
  16.    8      31st Jan 2001: Now default to 'DEVS:Modules/' dir if BKMODPATH
  17.           env variable cannot be found. Added IGNPATH option for completeness.
  18. */
  19.  
  20. /*
  21.   DESCRIPTION
  22.  
  23.     applypatch can be used to apply BlizKick "patch" kind of modules
  24.     to rom image. Useful if BlizKick doesn't support your system for
  25.     some reason, but you have a working maprom tool for it. applypatch
  26.     can also be used to speed up BlizKick booting by pre-patching rom
  27.     image. BlizKick commandline also gets quite a bit cleaner then. ;)
  28.  
  29.  
  30.   FEATURES
  31.  
  32.   - support for all patch modules that don't try to add resident tags
  33.   - includes HOGWAITBLIT patch of BlizKick
  34.   - includes SPEEDROM patch of BlizKick (kicktag reconnect)
  35.  
  36.  
  37.   RESTRICTIONS
  38.  
  39.   - works only with 512k ROM, 256K is obsolete really
  40.   - requires about 520k memory for patching
  41.   - for obvious reasons there is no undo :)
  42.  
  43.  
  44.   NOTES
  45.  
  46.   - It's a fairly good idea to keep the original ROM images somewhere
  47.     safe
  48.  
  49.  
  50.   SAMPLE RUN
  51.  
  52.     > applypatch DEVS:rom40068.A1200 TO T:rom40068.A1200.patched HOGWAITBLIT \
  53.       SPEEDROM NoClick FixMath404 SpeedyIDE PatchMath020 romfixes
  54.     reading kickfile "DEVS:rom40068.A1200"...
  55.     rom image ok, applying patches...
  56.     applying hogwaitblit patch...
  57.     applying NoClick patch...
  58.     applying FixMath404 patch...
  59.     applying SpeedyIDE patch...
  60.     applying PatchMath020 patch...
  61.     Patched DiceC Mulu routine at offset $27748
  62.     applying romfixes patch...
  63.     applying speedrom patch...
  64.  
  65.     ---- total 7 patches applied ----
  66.     calculating new checksum for image... $04E7630B
  67.     writing patched rom image to "T:rom40068.A1200.patched"...
  68.     done.
  69.  
  70.  
  71.   TODO
  72.  
  73.   - add support for non-EXTRESBUF InstallModule()
  74.   - add support for non-EXTRESBUF modules
  75.  
  76.  
  77.   AUTHOR & LEGAL CRAP
  78.  
  79.     applypatch is written by Harry "Piru" Sintonen 1999-2001.
  80.     applypatch is public domain.
  81.  
  82. */
  83.  
  84.  
  85. OPT OSVERSION=33
  86.  
  87. MODULE 'exec/memory','dos/dos','dos/var'
  88. MODULE 'hardware/dmabits'
  89.  
  90. ENUM ARG_KICKFILE,ARG_TO,ARG_MODULE,ARG_FORCE,ARG_SPEEDROM,
  91.      ARG_HOGWAITBLIT,ARG_IGNPATH,NUMARGS
  92.  
  93. DEF progname[64]:STRING,array[NUMARGS]:ARRAY OF LONG,
  94.     size=524288
  95.  
  96. PROC main()
  97.  
  98.   IF KickVersion(37)=0
  99.     WriteF('get real! this program requires kickstart 2.04+\n')
  100.     RETURN RETURN_FAIL
  101.   ENDIF
  102.  
  103.   GetProgramName(progname,63); SetStr(progname,StrLen(progname))
  104.  
  105. ENDPROC main2()
  106.  
  107. PROC main2()
  108.   DEF rdargs,r
  109.  
  110.   r:='$VER: applypatch 1.0.4 (31.1.01)'
  111.   FOR r:=0 TO NUMARGS-1; array[r]:=0; ENDFOR
  112.   IF (rdargs:=ReadArgs('FROM=KICKFILE/A,TO/K/A,MODULE/M,FORCE/S,' +
  113.                        'SPEEDROM/S,HOGWAITBLIT/S,' +
  114.                        'IGNPATH=IGNOREBKMODPATH/S',array,NIL))
  115.  
  116.     r:=main3(array[ARG_KICKFILE],array[ARG_MODULE])
  117.  
  118.     FreeArgs(rdargs)
  119.   ELSE
  120.     PrintFault(IoErr(),progname)
  121.     r:=RETURN_ERROR
  122.   ENDIF
  123. ENDPROC r
  124.  
  125. ENUM ROMSUMOFFS=$7FFE8,ROMSIZEOFFS=$7FFEC,ROMIDOFFS=$7FFF0,
  126.      BLIZKICK_ID="BlzK"
  127.  
  128. PROC main3(kickfile,modules:PTR TO LONG)
  129.   DEF r,rom:PTR TO LONG,fh,sum,suc=0,err=0
  130.   DEF modpath[256]:STRING,lock=NIL,olddir
  131.  
  132.   PrintF('reading kickfile "\s"...\n',kickfile)
  133.  
  134.   IF FileLength(kickfile)<>size
  135.     PrintF('kickfile "\s" length not \d\n',kickfile,size)
  136.     RETURN RETURN_ERROR
  137.   ENDIF
  138.  
  139.   IF (fh:=Open(kickfile,MODE_OLDFILE))=NIL
  140.     PrintFault(IoErr(),progname)
  141.     PrintF('could not open kickfile "\s"\n',kickfile)
  142.     RETURN RETURN_ERROR
  143.   ENDIF
  144.  
  145.   IF (rom:=New(size))=0
  146.     PrintFault(IoErr(),progname)
  147.     Close(fh)
  148.     PrintF('could not allocate \d bytes of memory\n',size)
  149.     RETURN RETURN_ERROR
  150.   ENDIF
  151.  
  152.   r:=Read(fh,rom,size); Close(fh); fh:=0
  153.   IF r<>size
  154.     PrintFault(IoErr(),progname)
  155.     PrintF('error reading kickfile "\s"\n',kickfile)
  156.     RETURN RETURN_ERROR
  157.   ENDIF
  158.  
  159.   IF (Long(rom+ROMSIZEOFFS)<>size) OR
  160.     ((rom[] AND $FFF8FFFF)<>$11104EF9)
  161.     PrintF('bad rom image!\n')
  162.     RETURN RETURN_ERROR
  163.   ENDIF
  164.  
  165.   r:=Long(rom+4) AND $FFFF0000
  166.   IF r<>$F80000
  167.     PrintF('rom image not located at $00F80000, but $\h[08]!\n',r)
  168.     RETURN RETURN_ERROR
  169.   ENDIF
  170.  
  171.   IF (sum:=romresum(rom,size))<>Long(rom+ROMSUMOFFS)
  172.     IF array[ARG_FORCE]
  173.       PrintF('bad rom checksum $\h[08] should be $\h[08], overrided ' +
  174.              'by FORCE/n',
  175.              sum,Long(rom+ROMSUMOFFS))
  176.     ELSE
  177.       PrintF('bad rom checksum $\h[08] should be $\h[08], can be\n' +
  178.              'overrided with FORCE switch\n',
  179.              sum,Long(rom+ROMSUMOFFS))
  180.       RETURN RETURN_ERROR
  181.     ENDIF
  182.   ENDIF
  183.  
  184.   IF Long(rom+ROMIDOFFS)=BLIZKICK_ID
  185.     IF array[ARG_FORCE]
  186.       PrintF('rom image has been used with BlizKick, but FORCE used\n')
  187.     ELSE
  188.       PrintF('rom image has been used with BlizKick before, can be\n' +
  189.              'overrided with FORCE switch\n')
  190.       RETURN RETURN_ERROR
  191.     ENDIF
  192.   ENDIF
  193.  
  194.   PrintF('rom image ok, applying patches...\n')
  195.  
  196.   -> apply hogwaitblit if enabled
  197.   IF array[ARG_HOGWAITBLIT]
  198.     PrintF('\e[1mapplying hogwaitblit patch...\e[22m\n')
  199.     IF puthogwaitblit(rom,size)
  200.       suc++
  201.     ELSE
  202.       err++
  203.       PrintF('could not patch!\n')
  204.     ENDIF
  205.   ENDIF
  206.  
  207.   IF modules
  208.  
  209.     IF array[ARG_IGNPATH] = 0
  210.       -> change dir to ENV:BKMODPATH or fallback to 'DEVS:Modules/'
  211.       IF GetVar('BKMODPATH',modpath,256,GVF_GLOBAL_ONLY) = -1
  212.         IF GetVar('ENVARC:BKMODPATH',modpath,256,GVF_GLOBAL_ONLY) = -1
  213.           StrCopy(modpath, 'DEVS:Modules/')
  214.         ENDIF
  215.       ENDIF
  216.       IF (lock:=Lock(modpath,ACCESS_READ))
  217.         olddir:=CurrentDir(lock)
  218.       ENDIF
  219.     ENDIF
  220.  
  221.     -> process all modules
  222.  
  223.     WHILE modules[]
  224.       PrintF('\e[1mapplying \s patch...\e[22m\n',modules[]); Flush(stdout)
  225.       IF applypatch(modules[],rom,size) THEN suc++ ELSE err++
  226.       modules++
  227.     ENDWHILE
  228.  
  229.     -> back to orig dir
  230.  
  231.     IF lock
  232.       CurrentDir(olddir)
  233.       UnLock(lock); lock:=0
  234.     ENDIF
  235.  
  236.   ENDIF
  237.  
  238.   -> apply speedrom, if enabled
  239.   IF array[ARG_SPEEDROM]
  240.     PrintF('\e[1mapplying speedrom patch...\e[22m\n')
  241.     IF speedrom(rom,size)
  242.       suc++
  243.     ELSE
  244.       err++
  245.       PrintF('could not patch!\n')
  246.     ENDIF
  247.   ENDIF
  248.  
  249.   IF err
  250.     PrintF('\n\d patch\s failed, output file "\s" not written\n',
  251.            err,IF err=1 THEN '' ELSE 'es',array[ARG_TO])
  252.   ELSE
  253.  
  254.     IF suc=0
  255.       PrintF('\n---- total 0 patches applied ----\ndestination file "\s" not written!\n',
  256.              array[ARG_TO])
  257.     ELSE
  258.  
  259.       PrintF('\n---- total \d patch\s applied ----\ncalculating new checksum for image...',
  260.              suc,IF suc=1 THEN '' ELSE 'es')
  261.  
  262.       -> resum rom
  263.  
  264.       PutLong(rom+ROMSUMOFFS,sum:=romresum(rom,size))
  265.  
  266.       PrintF(' $\h[08]\nwriting patched rom image to "\s"...\n',sum,array[ARG_TO])
  267.  
  268.       -> write rom
  269.  
  270.       IF (fh:=Open(array[ARG_TO],MODE_NEWFILE))=NIL
  271.         PrintFault(IoErr(),progname)
  272.         PrintF('could not open file "\s" for writing\n',array[ARG_TO])
  273.         RETURN RETURN_ERROR
  274.       ENDIF
  275.  
  276.       r:=Write(fh,rom,size); Close(fh); fh:=0
  277.       IF r<>size
  278.         PrintFault(IoErr(),progname)
  279.         DeleteFile(array[ARG_TO])
  280.         PrintF('error writing to "\s", destination file deleted\n',array[ARG_TO])
  281.         RETURN RETURN_ERROR
  282.       ENDIF
  283.     ENDIF
  284.  
  285.   ENDIF
  286.  
  287.   PrintF('done.\n')
  288.  
  289. ENDPROC
  290.  
  291. PROC puthogwaitblit(rom,size)
  292.  
  293.   MOVEM.L D1-D7/A0-A6,-(A7)
  294.  
  295.   MOVE.L  rom,A0
  296.   MOVE.L  size,D0
  297.  
  298.   MOVEQ   #0,D7
  299.  
  300.   CMP.W   #39,$C(A0)         -> Requires rom 39+
  301.   BCS.B   phwb_exit
  302.  
  303.   LEA     -4(A0,D0.L),A1
  304.  
  305.   MOVE.L  #$08390006,D0
  306.   phwb_find:
  307.   ADDQ.L  #2,A0
  308.   CMPA.L  A1,A0
  309.   BEQ.B   phwb_exit
  310.   CMP.L   (A0),D0
  311.   BNE.B   phwb_find
  312.   CMP.L   #$00DFF002,4(A0)
  313.   BNE.B   phwb_find
  314.   CMP.L   #$66024E75,8(A0)
  315.   BNE.B   phwb_find
  316.  
  317.   CMP.L   #$08390006,-8(A0)  -> No KS 1.x!
  318.   BEQ.B   phwb_exit
  319.   CMP.L   #$4A3900DF,-6(A0)  -> KS 2.x/3.x:
  320.   BNE.B   phwb_exit
  321.   SUBQ.L  #6,A0
  322.   LEA     phwb_waitblit(PC),A1
  323.   MOVEQ   #21,D0             -> 42/2
  324.   phwb_copy:
  325.   MOVE.W  (A1)+,(A0)+
  326.   SUBQ.L  #1,D0
  327.   BNE.B   phwb_copy
  328.   MOVEQ   #1,D7
  329.  
  330.   phwb_exit:
  331.   MOVE.L  D7,D0
  332.   MOVEM.L (A7)+,D1-D7/A0-A6
  333.   RETURN  D0
  334.  
  335.   -> 3.0  48 bytes
  336.   -> 3.1  48 bytes
  337.   phwb_waitblit:
  338.   BTST    #6,$DFF002         -> 8 DMAB_BLTDONE=14 dmaconr
  339.   BNE.B   phwb_wb_gowait     -> 2
  340.   RTS                        -> 2
  341.   phwb_wb_gowait:
  342.   MOVE.L  A0,-(A7)           -> 2
  343.   LEA     $DFF002,A0         -> 6 dmaconr
  344.   MOVE.W  #$8400,148(A0)     -> 6 DMAF_SETCLR OR DMAF_BLITHOG dmacon-dmaconr
  345.   phwb_wb_wait:
  346.   BTST    #6,(A0)            -> 4 DMAB_BLTDONE=14 DMAB_BLTDONE-8
  347.   BNE.B   phwb_wb_wait       -> 2
  348.   MOVE.W  #$0400,148(A0)     -> 6 DMAF_BLITHOG dmacon-dmaconr
  349.   MOVE.L  (A7)+,A0           -> 2
  350.   RTS                        -> 2 =42
  351.  
  352. ENDPROC
  353.  
  354. PROC speedrom(rom,size)
  355.  
  356.   -> Reconnect resident modules:
  357.  
  358.   MOVEM.L D1-D7/A0-A6,-(A7)
  359.  
  360.   MOVE.L  rom,A0
  361.   MOVE.L  size,D0
  362.  
  363.   MOVE.L  #$01000000,D2
  364.   SUB.L   D0,D2
  365.   MOVE.L  A0,A5
  366.   SUB.L   D2,A5      -> a5=difference
  367.  
  368.   MOVEQ   #-28,D1    -> -(RT_SIZE+2),D1
  369.   ADD.L   D0,D1
  370.   SUB.L   A1,A1
  371.   sr_find:
  372.   SUBQ.L  #2,D1
  373.   BLS.B   sr_done
  374.   CMP.W   #$4AFC,(A0)+  -> RTC_MATCHWORD,(A0)+
  375.   BNE.B   sr_find
  376.   MOVEQ   #2,D0
  377.   ADD.L   (A0),D0    -> RT_MATCHTAG-2(A0),D0
  378.   ADD.L   A5,D0
  379.   CMP.L   A0,D0
  380.   BNE.B   sr_find
  381.   SUBQ.L  #2,A0
  382.   MOVE.L  A1,D0
  383.   BEQ.B   sr_is_1st
  384.   MOVE.L  A0,D0
  385.   SUB.L   A5,D0
  386.   MOVE.L  D0,6(A1)   -> RT_ENDSKIP(A1)
  387.   sr_is_1st:
  388.   MOVE.L  A0,A1
  389.   LEA     26(A0),A0  ->RT_SIZE(A0),A0
  390.   BRA.B   sr_find
  391.   sr_done:
  392.   MOVE.L  A1,D0
  393.   BEQ.B   sr_none
  394.   -> make last RT_ENDSKIP point $00FFFFFA
  395.   MOVE.L  #$00FFFFFA,6(A1)
  396.   sr_none:
  397.   MOVEQ   #1,D7
  398.  
  399.   MOVE.L  D7,D0
  400.   MOVEM.L (A7)+,D1-D7/A0-A6
  401. ENDPROC D0
  402.  
  403. ENUM BKMODULE_ID=$707A4E75,BKEP_ID=$4E71
  404.  
  405. PROC applypatch(patch,rom,size)
  406.   DEF ret=0,seg,module:PTR TO LONG
  407.  
  408.   IF (seg:=Lock(patch,ACCESS_READ))
  409.     UnLock(seg)
  410.  
  411.     IF (seg:=LoadSeg(patch))
  412.  
  413.       module:=Shl(seg,2)+4
  414.  
  415.       IF module[]=BKMODULE_ID
  416.         IF module[1]=BKEP_ID
  417.  
  418.           MOVEM.L D1-D7/A0-A6,-(A7)
  419.           LEA     findresident(PC),A2
  420.           LEA     installmodule(PC),A3
  421.           MOVE.L  dosbase,D6
  422.           MOVE.L  execbase,A6
  423.           MOVE.L  rom,A0
  424.           LEA     $F80000,A1
  425.           MOVE.L  #$80000,D0
  426.           MOVE.L  module,A5
  427.           LEA     printf(PC),A4
  428.           JSR     8(A5)
  429.           MOVEM.L (A7)+,D1-D7/A0-A6
  430.           MOVE.L  D0,ret
  431.  
  432.           IF ret=0
  433.             PrintF('failed, module returned error\n')
  434.           ENDIF
  435.  
  436.         ELSE
  437.           PrintF('failed, only patch modules supported!\n')
  438.         ENDIF
  439.       ELSE
  440.         PrintF('failed, not a blizkick module!\n')
  441.       ENDIF
  442.  
  443.       UnLoadSeg(seg)
  444.     ELSE
  445.       PrintFault(IoErr(),progname)
  446.       PrintF('failed, could not load module!\n')
  447.     ENDIF
  448.   ELSE
  449.     PrintFault(IoErr(),progname)
  450.     PrintF('failed, could not load module!\n')
  451.   ENDIF
  452.   RETURN ret
  453.  
  454.  
  455. ->  IN: a0=ptr to ROM, d0=rom len, a1=ptr to resident name
  456. -> OUT: d0=ptr to resident (buf) or NULL
  457. findresident:
  458.   MOVEM.L D1-D7/A0-A6,-(A7)
  459.   MOVEQ   #1,D6
  460.   MOVE.L  A1,A3
  461.   MOVE.L  #$01000000,D2
  462.   SUB.L   D0,D2      -> d2=rom start (rom)
  463.   MOVE.L  A0,A5
  464.   SUB.L   D2,A5      -> A5=diff
  465.   MOVEQ   #26-2,D1   ->RT_SIZE-2,D1
  466.   SUB.L   D1,D0
  467.   MOVE.W  #$4AFC,D1  ->RTC_MATCHWORD,D1
  468.   fr_find:
  469.   SUBQ.L  #2,D0
  470.   BLS.B   fr_exit_nf
  471.   CMP.W   (A0)+,D1
  472.   BNE.B   fr_find
  473.   MOVEQ   #2,D2
  474.   ADD.L   (A0),D2    ->RT_MATCHTAG-2(A0),D2
  475.   ADD.L   A5,D2
  476.   CMP.L   A0,D2
  477.   BNE.B   fr_find
  478.   MOVE.L  12(A0),A1  ->RT_NAME-2(A0),A1
  479.   ADD.L   A5,A1
  480.   MOVE.L  A3,A2
  481.   fr_compare:
  482.   CMPM.B  (A2)+,(A1)+
  483.   BNE.B   fr_find
  484.   TST.B   -1(A2)
  485.   BNE.B   fr_compare
  486.  
  487.   MOVE.L  A0,D0
  488.   SUBQ.L  #2,D0
  489.  
  490.   fr_exit2:
  491.   MOVEM.L (A7)+,D1-D7/A0-A6
  492.   RTS
  493.  
  494.   fr_exit_nf:
  495.   MOVEQ   #0,D0
  496.   BRA.B   fr_exit2
  497.  
  498.  
  499. ->  IN: a0=ptr to ROM, d0=rom len, a1=ptr to module, d6=dosbase
  500. -> OUT: d0=success
  501. installmodule:
  502.   MOVEQ   #0,D0
  503.   RTS
  504.  
  505. ->  IN: a0=FmtString, a1=Array (may be 0), d6=dosbase
  506. printf:
  507.   EXG     D6,A6
  508.   MOVEM.L D0-D2/A0-A1,-(A7)
  509.   MOVE.L  A0,D1
  510.   MOVE.L  A1,D2
  511.   JSR     -$3BA(A6)   -> _LVOVPrintF
  512.   MOVEM.L (A7)+,D0-D2/A0-A1
  513.   EXG     D6,A6
  514.   RTS
  515.  
  516. ENDPROC
  517.  
  518.  
  519. PROC romresum(rom,size)
  520.   MOVE.L  rom,A0
  521.   MOVE.L  size,D0
  522.   MOVE.L  D0,D1
  523.   LSR.L   #2,D1
  524.   MOVE.L  -$18(A0,D0.L),D0
  525.   NOT.L   D0
  526.   rr_loop:
  527.   ADD.L   (A0)+,D0
  528.   BCC.B   rr_skip
  529.   ADDQ.L  #1,D0
  530.   rr_skip:
  531.   SUBQ.L  #1,D1
  532.   BNE.B   rr_loop
  533.   NOT.L   D0
  534. ENDPROC D0
  535.